#ifndef HANDLEHTASK_HPP
#define HANDLEHTASK_HPP

#include <stdio.h>
#include <cassert>
#include <string>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <sstream>
#include "json11/json11.hpp"
#include <list>
#include <set>
#include <unordered_map>
#include <algorithm>
#include <type_traits>
#include <fstream>
#include "sys/io.h"
#include <unistd.h>

using namespace std;
using namespace json11;

int judgeNameInTaskJson(string name,Json::array task_array){
    for(int k=0;k<task_array.size();k++){
        if(name==task_array[k]["task_name"].string_value()){
            return 1;//exist
        }
    }
    return 0;//not exist	
}
void writeTaskJson(Json::array t_total,string file_path){
	int p_num = t_total.size();

	ofstream inputJson(file_path.c_str(), ios::trunc);
	if(!inputJson.is_open()){
		cout << "failed to open task.json" << endl;
		return ;
	}

	string sspace = "			";
	string ssspace = "				";
	string sssspace = "					";
	// write json
	inputJson << "{" << endl;
	inputJson << "	" << "\"data\": [" << endl;

	for (int i = 0; i < p_num; i++) {

		inputJson << "		" << "{" << endl;
		inputJson << sspace << "\"task_name\"" << ":  " << "\"" << t_total[i]["task_name"].string_value() << "\"" << "," << endl;
		inputJson << sspace << "\"map_name\"" << ":  " << "\"" << t_total[i]["map_name"].string_value() << "\"" << "," << endl;
		
		Json::array temp_path = t_total[i]["use_path"].array_items();
		int t_num = temp_path.size();
		inputJson << sspace << "\"use_path\"" << ": " << "[" << endl;
		for (int j = 0; j < t_num; j++) {
			
			inputJson << ssspace << "{ " << "\"type\"" << ": " << "\"" << t_total[i]["use_path"][j]["type"].string_value() << "\"" << "," << endl;
			inputJson << ssspace << "\"name\"" << ": " << "\"" << t_total[i]["use_path"][j]["name"].string_value() << "\"" << "," << endl;
			inputJson << ssspace << "\"motor_level\"" << ": " <<endl;
			inputJson << ssspace << "{" << endl;
			inputJson << sssspace << "\"brushLevel\"" << ": " << t_total[i]["use_path"][j]["motor_level"]["brushLevel"].int_value() << "," << endl;
			inputJson << sssspace << "\"brushLift\"" << ": " << t_total[i]["use_path"][j]["motor_level"]["brushLift"].int_value() << "," << endl;
			inputJson << sssspace << "\"waterSpray\"" << ": "  << t_total[i]["use_path"][j]["motor_level"]["waterSpray"].int_value() << "," << endl;
			inputJson << sssspace << "\"wiperLift\"" << ": " << t_total[i]["use_path"][j]["motor_level"]["wiperLift"].int_value() << "," << endl;
			inputJson << sssspace << "\"vacuum\"" << ": "  << t_total[i]["use_path"][j]["motor_level"]["vacuum"].int_value()  << ","<< endl;
			inputJson << sssspace << "\"shakeLevel\"" << ": "  << t_total[i]["use_path"][j]["motor_level"]["shakeLevel"].int_value() << endl;
			inputJson << ssspace << "}" << endl;
			inputJson << ssspace << "}";
			if (j < (t_num - 1)) {
				inputJson << "," << endl;
			}

		}
		inputJson << "]" << endl;

		inputJson << "		" << "}";
		if (i < (p_num - 1)) {
			inputJson << "," << endl;
		}
	}
	inputJson << "	" << "]" << endl;
	inputJson << "}";
	inputJson.close();
	return ;
}

int taskWrite(Json t1, string file_path) {
	Json::array t_total;
	if (access(file_path.c_str(), 0) != 0) {
		//creat new task.json
		ofstream out_file(file_path.c_str());
		if(!out_file.is_open()){
			cout << "failed to open task.json" << endl;
			return -1;
		}
		out_file.close();
	}
	else {

		ifstream in_file(file_path.c_str());
		if(!in_file.is_open()){
			cout << "failed to open task.json" << endl;
			return -1;
		}
		stringstream buffer;
		string err;
		buffer << in_file.rdbuf();
		//cout << "parse result: " << buffer.str() << endl;
		Json test_tmp = Json::parse(buffer.str(), err);
		t_total = test_tmp["data"].array_items();
		//cout << test_tmp.dump() << endl;
		in_file.close();
	}

	t_total.push_back(t1);
	
	writeTaskJson(t_total,file_path);

	cout<<"taskWrite successful!"<<file_path<<endl;
	return 0;
}

int taskEdit(Json t1, string file_path) {
	Json::array t_total;
	cout<<t1.dump()<<endl;
	if (access(file_path.c_str(), 0) != 0) {
		//creat new task.json
		ofstream out_file(file_path.c_str());
		if(!out_file.is_open()){
			cout << "failed to open task.json" << endl;
			return -1;
		}
		out_file.close();
	}
	else {

		ifstream in_file(file_path.c_str());
		if(!in_file.is_open()){
			cout << "failed to open task.json" << endl;
			return -1;
		}
		stringstream buffer;
		string err;
		buffer << in_file.rdbuf();
		//cout << "parse result: " << buffer.str() << endl;
		Json test_tmp = Json::parse(buffer.str(), err);
		t_total = test_tmp["data"].array_items();
		//cout << test_tmp.dump() << endl;
		in_file.close();
	}
	int p_num = t_total.size();
	// string s_temp;
	Json::object object_;
    Json::array task_info;
	for(int i = 0; i<p_num;i++){
		if (t1["task_name"].string_value()==t_total[i]["task_name"].string_value()){	
			ROS_INFO("start Edit task");
			task_info.push_back(t1);
		}else{
			object_ = t_total[i].object_items();
			Json task_list_(object_);
			task_info.push_back(task_list_);
		}
	}

	writeTaskJson(task_info,file_path);

	return 0;
}


int taskMapEdit(string newMapName, string file_path) {
	Json::array t_total;
	if (access(file_path.c_str(), 0) != 0) {
		
		cout << "file do not exist!!" << endl;
		return -1;
	}
	else {

		ifstream in_file(file_path.c_str());
		if(!in_file.is_open()){
			cout << "failed to open task.json" << endl;
			return -1;
		}
		stringstream buffer;
		string err;
		buffer << in_file.rdbuf();
		//cout << "parse result: " << buffer.str() << endl;
		Json test_tmp = Json::parse(buffer.str(), err);
		t_total = test_tmp["data"].array_items();
		//cout << test_tmp.dump() << endl;
		in_file.close();
	}
	int p_num = t_total.size();
	// string s_temp;

	Json::object object_;
    Json::array task_info;
	for(int i = 0; i<p_num;i++){
		object_ = t_total[i].object_items();
		object_["map_name"] = newMapName;
		
		Json map_list_(object_);
		task_info.push_back(map_list_);
	}

	writeTaskJson(task_info,file_path);

	cout<<"taskMapEdit successful!"<<file_path<<endl;
	return 0;

}

int taskRename(string oldtaskName, string newtaskName, string file_path) {
	Json::array t_total;
	if (access(file_path.c_str(), 0) != 0) {
		
		cout << "file do not exist!!" << endl;
		return -1;
	}
	else {

		ifstream in_file(file_path.c_str());
		if(!in_file.is_open()){
			cout << "failed to open task.json" << endl;
			return -1;
		}
		stringstream buffer;
		string err;
		buffer << in_file.rdbuf();
		//cout << "parse result: " << buffer.str() << endl;
		Json test_tmp = Json::parse(buffer.str(), err);
		t_total = test_tmp["data"].array_items();
		//cout << test_tmp.dump() << endl;
		in_file.close();
	}
	int p_num = t_total.size();
	// string s_temp;

	Json::object object_;
    Json::array task_info;
	for(int i = 0; i<p_num;i++){
		object_ = t_total[i].object_items();
	
		if (t_total[i]["task_name"].string_value() == oldtaskName){	
			object_["task_name"] = newtaskName;
		}
		Json map_list_(object_);
		task_info.push_back(map_list_);
	}

	writeTaskJson(task_info,file_path);
	cout<<"taskRename successful!"<<file_path<<endl;
	return 0;

}

int taskdelete(string taskkey, string file_path) {
	Json::array t_total;
	if (access(file_path.c_str(), 0) != 0) {
		
		cout << "file do not exist!!" << endl;
		return -1;
	}
	else {

		ifstream in_file(file_path.c_str());
		if(!in_file.is_open()){
			cout << "failed to open task.json" << endl;
			return -1;
		}
		stringstream buffer;
		string err;
		buffer << in_file.rdbuf();
		//cout << "parse result: " << buffer.str() << endl;
		Json test_tmp = Json::parse(buffer.str(), err);
		t_total = test_tmp["data"].array_items();
		//cout << test_tmp.dump() << endl;
		in_file.close();
	}
	int p_num = t_total.size();
	// string s_temp;
	Json::object object_;
    Json::array task_info;
	for(int i = 0; i<p_num;i++){
		object_ = t_total[i].object_items();
	
		if (t_total[i]["task_name"].string_value() != taskkey){	
			Json map_list_(object_);
			task_info.push_back(map_list_);
		}
		
	}
	writeTaskJson(task_info,file_path);
	cout<<"taskdelete successful!"<<file_path<<endl;
	return 0;

}
#endif